{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\Anaconda install\\envs\\Gym\\lib\\site-packages\\gym\\envs\\registration.py:555: UserWarning: \u001b[33mWARN: The environment CartPole-v0 is out of date. You should consider upgrading to version `v1`.\u001b[0m\n",
      "  logger.warn(\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([-3.6975097e-02, -6.9951755e-03, -1.6136264e-02, -9.3689661e-05],\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import gym\n",
    "\n",
    "\n",
    "#定义环境\n",
    "class MyWrapper(gym.Wrapper):\n",
    "    def __init__(self):\n",
    "        env = gym.make('CartPole-v0', render_mode='rgb_array')\n",
    "        super().__init__(env)\n",
    "        self.env = env\n",
    "        self.step_n = 0\n",
    "\n",
    "    def reset(self):\n",
    "        state, _ = self.env.reset()\n",
    "        self.step_n = 0\n",
    "        return state\n",
    "\n",
    "    def step(self, action):\n",
    "        state, reward, terminated, truncated, info = self.env.step(action)\n",
    "        done = terminated or truncated\n",
    "        self.step_n += 1\n",
    "        if self.step_n >= 200:\n",
    "            done = True\n",
    "        return state, reward, done, info\n",
    "\n",
    "\n",
    "env = MyWrapper()\n",
    "\n",
    "env.reset()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "\n",
    "#打印游戏\n",
    "def show():\n",
    "    plt.imshow(env.render())\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0.5263, 0.4737],\n",
       "         [0.5392, 0.4608]], grad_fn=<SoftmaxBackward0>),\n",
       " tensor([[-0.3064],\n",
       "         [-0.2110]], grad_fn=<AddmmBackward0>))"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "#定义模型\n",
    "# 定义两个模型 分别是：策略梯度模型，时序差分模型\n",
    "model = torch.nn.Sequential(\n",
    "    torch.nn.Linear(4,128),\n",
    "    torch.nn.ReLU(),\n",
    "    torch.nn.Linear(128,2),\n",
    "    torch.nn.Softmax(dim=1)\n",
    ")\n",
    "model_td = torch.nn.Sequential(\n",
    "    torch.nn.Linear(4,128),\n",
    "    torch.nn.ReLU(),\n",
    "    torch.nn.Linear(128,1),\n",
    ")\n",
    "model(torch.randn(2,4)),model_td(torch.randn(2,4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import random\n",
    "#得到一个动作\n",
    "def get_action(state):\n",
    "    state = torch.FloatTensor(state).reshape(1,4)\n",
    "\n",
    "    prob = model(state)\n",
    "\n",
    "    #根据概率选择一个动作\n",
    "    action  = random.choices(range(2),weights=prob[0].tolist())[0]\n",
    "    return action\n",
    "get_action([1,2,3,4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\cgq10\\AppData\\Local\\Temp\\ipykernel_27140\\2609820583.py:31: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at C:\\actions-runner\\_work\\pytorch\\pytorch\\builder\\windows\\pytorch\\torch\\csrc\\utils\\tensor_new.cpp:248.)\n",
      "  states = torch.FloatTensor(states).reshape(-1,4)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(tensor([[ 3.2387e-02,  4.4192e-02, -2.0273e-02,  4.6093e-02],\n",
       "         [ 3.3271e-02, -1.5063e-01, -1.9351e-02,  3.3231e-01],\n",
       "         [ 3.0258e-02, -3.4547e-01, -1.2704e-02,  6.1883e-01],\n",
       "         [ 2.3349e-02, -5.4042e-01, -3.2786e-04,  9.0748e-01],\n",
       "         [ 1.2540e-02, -3.4529e-01,  1.7822e-02,  6.1470e-01],\n",
       "         [ 5.6345e-03, -1.5042e-01,  3.0116e-02,  3.2768e-01],\n",
       "         [ 2.6261e-03, -3.4596e-01,  3.6669e-02,  6.2971e-01],\n",
       "         [-4.2931e-03, -1.5137e-01,  4.9264e-02,  3.4879e-01],\n",
       "         [-7.3205e-03,  4.3020e-02,  5.6240e-02,  7.2044e-02],\n",
       "         [-6.4601e-03,  2.3729e-01,  5.7680e-02, -2.0238e-01],\n",
       "         [-1.7142e-03,  4.3154e-01,  5.3633e-02, -4.7632e-01],\n",
       "         [ 6.9167e-03,  6.2587e-01,  4.4106e-02, -7.5163e-01],\n",
       "         [ 1.9434e-02,  8.2036e-01,  2.9074e-02, -1.0301e+00],\n",
       "         [ 3.5841e-02,  1.0151e+00,  8.4715e-03, -1.3135e+00],\n",
       "         [ 5.6143e-02,  8.1985e-01, -1.7799e-02, -1.0182e+00],\n",
       "         [ 7.2540e-02,  1.0152e+00, -3.8163e-02, -1.3164e+00],\n",
       "         [ 9.2844e-02,  1.2108e+00, -6.4492e-02, -1.6208e+00],\n",
       "         [ 1.1706e-01,  1.0165e+00, -9.6908e-02, -1.3489e+00],\n",
       "         [ 1.3739e-01,  8.2270e-01, -1.2389e-01, -1.0880e+00],\n",
       "         [ 1.5384e-01,  6.2941e-01, -1.4565e-01, -8.3665e-01],\n",
       "         [ 1.6643e-01,  4.3655e-01, -1.6238e-01, -5.9309e-01],\n",
       "         [ 1.7516e-01,  2.4403e-01, -1.7424e-01, -3.5564e-01],\n",
       "         [ 1.8004e-01,  5.1756e-02, -1.8135e-01, -1.2256e-01],\n",
       "         [ 1.8108e-01,  2.4895e-01, -1.8381e-01, -4.6653e-01],\n",
       "         [ 1.8606e-01,  4.4613e-01, -1.9314e-01, -8.1105e-01],\n",
       "         [ 1.9498e-01,  6.4330e-01, -2.0936e-01, -1.1577e+00]]),\n",
       " tensor([[1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.],\n",
       "         [1.]]),\n",
       " tensor([[0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [1],\n",
       "         [1],\n",
       "         [0],\n",
       "         [1],\n",
       "         [1],\n",
       "         [1],\n",
       "         [1],\n",
       "         [1],\n",
       "         [1],\n",
       "         [1],\n",
       "         [0],\n",
       "         [1],\n",
       "         [1],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [1],\n",
       "         [1],\n",
       "         [1],\n",
       "         [0]]),\n",
       " tensor([[ 3.3271e-02, -1.5063e-01, -1.9351e-02,  3.3231e-01],\n",
       "         [ 3.0258e-02, -3.4547e-01, -1.2704e-02,  6.1883e-01],\n",
       "         [ 2.3349e-02, -5.4042e-01, -3.2786e-04,  9.0748e-01],\n",
       "         [ 1.2540e-02, -3.4529e-01,  1.7822e-02,  6.1470e-01],\n",
       "         [ 5.6345e-03, -1.5042e-01,  3.0116e-02,  3.2768e-01],\n",
       "         [ 2.6261e-03, -3.4596e-01,  3.6669e-02,  6.2971e-01],\n",
       "         [-4.2931e-03, -1.5137e-01,  4.9264e-02,  3.4879e-01],\n",
       "         [-7.3205e-03,  4.3020e-02,  5.6240e-02,  7.2044e-02],\n",
       "         [-6.4601e-03,  2.3729e-01,  5.7680e-02, -2.0238e-01],\n",
       "         [-1.7142e-03,  4.3154e-01,  5.3633e-02, -4.7632e-01],\n",
       "         [ 6.9167e-03,  6.2587e-01,  4.4106e-02, -7.5163e-01],\n",
       "         [ 1.9434e-02,  8.2036e-01,  2.9074e-02, -1.0301e+00],\n",
       "         [ 3.5841e-02,  1.0151e+00,  8.4715e-03, -1.3135e+00],\n",
       "         [ 5.6143e-02,  8.1985e-01, -1.7799e-02, -1.0182e+00],\n",
       "         [ 7.2540e-02,  1.0152e+00, -3.8163e-02, -1.3164e+00],\n",
       "         [ 9.2844e-02,  1.2108e+00, -6.4492e-02, -1.6208e+00],\n",
       "         [ 1.1706e-01,  1.0165e+00, -9.6908e-02, -1.3489e+00],\n",
       "         [ 1.3739e-01,  8.2270e-01, -1.2389e-01, -1.0880e+00],\n",
       "         [ 1.5384e-01,  6.2941e-01, -1.4565e-01, -8.3665e-01],\n",
       "         [ 1.6643e-01,  4.3655e-01, -1.6238e-01, -5.9309e-01],\n",
       "         [ 1.7516e-01,  2.4403e-01, -1.7424e-01, -3.5564e-01],\n",
       "         [ 1.8004e-01,  5.1756e-02, -1.8135e-01, -1.2256e-01],\n",
       "         [ 1.8108e-01,  2.4895e-01, -1.8381e-01, -4.6653e-01],\n",
       "         [ 1.8606e-01,  4.4613e-01, -1.9314e-01, -8.1105e-01],\n",
       "         [ 1.9498e-01,  6.4330e-01, -2.0936e-01, -1.1577e+00],\n",
       "         [ 2.0785e-01,  4.5143e-01, -2.3251e-01, -9.3731e-01]]),\n",
       " tensor([[0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [0],\n",
       "         [1]]))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def get_data():\n",
    "    # 得到一句游戏的数据\n",
    "    states=[]\n",
    "    rewards=[]\n",
    "    actions=[]\n",
    "    next_states=[]\n",
    "    overs=[]\n",
    "\n",
    "    #初始化游戏\n",
    "    state = env.reset()\n",
    "\n",
    "    #玩到游戏结束为止\n",
    "    over = False\n",
    "    while not over:\n",
    "        #根据当前状态得到一个动作\n",
    "        action = get_action(state)\n",
    "\n",
    "        #执行动作，得到反馈\n",
    "        next_state,reward,over,_=env.step(action)\n",
    "\n",
    "        #记录数据样本\n",
    "        states.append(state)\n",
    "        rewards.append(reward)\n",
    "        actions.append(action)\n",
    "        next_states.append(next_state)\n",
    "        overs.append(over)\n",
    "\n",
    "        #更新游戏状态，开始下一个动作\n",
    "        state = next_state\n",
    "\n",
    "    states = torch.FloatTensor(states).reshape(-1,4)\n",
    "\n",
    "    rewards = torch.FloatTensor(rewards).reshape(-1,1)\n",
    "\n",
    "    actions = torch.LongTensor(actions).reshape(-1,1)\n",
    "\n",
    "    next_states = torch.FloatTensor(next_states).reshape(-1,4)\n",
    "\n",
    "    overs = torch.LongTensor(overs).reshape(-1,1)\n",
    "    return states,rewards,actions,next_states,overs\n",
    "get_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "18.0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython import display\n",
    "\n",
    "\n",
    "def test(play):\n",
    "    #初始化游戏\n",
    "    state = env.reset()\n",
    "\n",
    "    #记录反馈值的和,这个值越大越好\n",
    "    reward_sum = 0\n",
    "\n",
    "    #玩到游戏结束为止\n",
    "    over = False\n",
    "    \n",
    "    while not over:\n",
    "        \n",
    "        #根据当前状态得到一个动作\n",
    "        action = get_action(state)\n",
    "\n",
    "        #执行动作,得到反馈\n",
    "        state, reward, over, _ = env.step(action)\n",
    "        reward_sum += reward\n",
    "\n",
    "        #打印动画\n",
    "        if play: \n",
    "            display.clear_output(wait=True)\n",
    "            show()\n",
    "\n",
    "    return reward_sum\n",
    "\n",
    "\n",
    "test(play=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch:0,score:32.1\n",
      "epoch:100,score:41.0\n",
      "epoch:200,score:45.9\n",
      "epoch:300,score:108.7\n",
      "epoch:400,score:141.9\n",
      "epoch:500,score:153.3\n",
      "epoch:600,score:178.1\n",
      "epoch:700,score:199.6\n",
      "epoch:800,score:200.0\n",
      "epoch:900,score:200.0\n"
     ]
    }
   ],
   "source": [
    "def train():\n",
    "    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)\n",
    "    optimizer_td = torch.optim.Adam(model_td.parameters(), lr=1e-2)\n",
    "    loss_fn = torch.nn.MSELoss()\n",
    "\n",
    "    for i in range(1000):\n",
    "        states, rewards, actions, next_states, overs = get_data()\n",
    "\n",
    "        values = model_td(states)\n",
    "\n",
    "        targets = model_td(next_states) * 0.98\n",
    "\n",
    "        targets *= 1 - overs\n",
    "\n",
    "        targets += rewards\n",
    "\n",
    "\n",
    "\n",
    "        delta = (targets - values).detach()\n",
    "\n",
    "        probs = model(states)\n",
    "\n",
    "        probs = probs.gather(dim=1, index=actions)\n",
    "\n",
    "        loss = (-probs.log() * delta).mean()\n",
    "\n",
    "        loss_td = loss_fn(values, targets.detach())\n",
    "\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        optimizer_td.zero_grad()\n",
    "        loss_td.backward()\n",
    "        optimizer_td.step()\n",
    "\n",
    "        if i % 100 == 0:\n",
    "            test_result = sum([test(play=False) for _ in range(10)]) / 10\n",
    "            print(f\"epoch:{i},score:{test_result}\")\n",
    "\n",
    "\n",
    "train()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "200.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test(play=True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Gym",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.16"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
